/** 
 * @defgroup gui gui
 * main gui routines
 * @{
 */

#include <string.h> 
#include "config.h"
#include "main.h"
#include "source.h"
#include "sensor.h"
#include "output.h"
#include "warp.h"
#include "thresh.h"
#include "prefs.h"
#include "gstreamer.h"
#include "gui.h"


static struct Gui
{
    char *gladefile;        /* the name of the glade-file to use */
    GladeXML *glade_xml;    /* our XML-Pointer to interact with Glade */
    GtkWidget *drawingarea_src; /* source preview */
    GtkWidget *drawingarea_dst; /* output preview */
    GtkTreeStore *source_tree, *sensor_tree; /* TreeStores to store list of sources/sensors */
}gui;


/**
 * gladefile setter
 * @param filename of glade-file
 */
void gui_set_gladefile(char *name)
{
    gui.gladefile = name;
}

/**
 * gladefile getter
 * @result filename of glade-file
 */
char *gui_get_gladefile()
{
    return gui.gladefile;
}

/**
 * get dest-drawingarea
 * @result GtkWidget drawingarea
 */
GtkWidget *gui_get_da_dst()
{
    if(!(gui.drawingarea_dst))
        _VERBOSE3 printf("%s(): returned NULL pointer!\n", __func__);
    return gui.drawingarea_dst;
}

/**
 * get src-drawingarea
 * @result GtkWidget drawingarea
 */
GtkWidget *gui_get_da_src()
{
    if(!(gui.drawingarea_src))
        _VERBOSE3 printf("%s(): returned NULL pointer!\n", __func__);
    return gui.drawingarea_src;
}

/**
 * drawingarea_src setter
 */
void gui_set_da_src(GtkWidget *w)
{
    gui.drawingarea_src = w;
}

/**
 * get glade-xml
 * @result GladeXML glade_xml structure
 */
GladeXML *gui_get_xml()
{
    if(!(gui.glade_xml))
        _VERBOSE3 printf("%s(): returned NULL pointer!\n", __func__);
    return gui.glade_xml;
}



/************************** GTK-Callbacks **************************/
/**
 * main quit 
 */
gboolean cb_main_quit(GtkWidget * window, GdkEvent * event)
{
    /*
     * quit gtk 
     */
    gtk_main_quit();
    return FALSE;
}

/**
 * warning-dialog has been closed
 */
gboolean cb_dialog_close(GtkWidget * widget)
{
    _VERBOSE2 printf("%s()\n", __func__);
    
    gtk_widget_hide(glade_xml_get_widget
                    (gui_get_xml(), "dialog_warning"));
    return TRUE;
}

/**
 * show/hide about-dialog
 */
gboolean cb_about_dialog(GtkWidget *widget)
{
    
    _VERBOSE2 printf("%s()\n", __func__);

    if(GTK_WIDGET_VISIBLE(glade_xml_get_widget(gui.glade_xml, "dialog_about")))
    {
        gtk_widget_hide(glade_xml_get_widget(gui.glade_xml, "dialog_about"));
    }
    else
    {
        gtk_widget_show(glade_xml_get_widget(gui.glade_xml, "dialog_about"));
    }
    
    return TRUE;
}
/************************** Module **************************/
/**
 * cleanup gui-module
 */
void gui_cleanup()
{
    gui.glade_xml = NULL;
    
    free(gui.gladefile);
    gui.gladefile = NULL;
}

/**
 * initialize gui-module
 */
int gui_init()
{
    char temp[255];

   
    /*
     * init gui 
     */
    snprintf((char *) &temp, 255, "%s/%s/glade/%s", DATADIR, PACKAGE,
                        gui.gladefile);
    _VERBOSE1 printf("gui_init(): using glade-file \"%s\"\n",
                     (char *) &temp);
    
    if((gui.glade_xml = glade_xml_new((char *) &temp, NULL, NULL)))
    {
        /*
         * connect signals 
         */
        glade_xml_signal_autoconnect(gui.glade_xml);

        /*
         * get widgets 
         */
        gui_set_da_src(glade_xml_get_widget(gui.glade_xml, "drawingarea_input"));
        
        gui.drawingarea_dst =
            glade_xml_get_widget(gui.glade_xml, "drawingarea_output");
        
    
        
        /* initialize sensor-gui */
        if(sensor_gui_init() < 0)
        {
            return -1;
        }
        
        /* initialize warp-gui */
        if(warp_gui_init() < 0)
        {
            return -1;
        }
        
        /* initialize preview-gui */
        if(src_gui_init() < 0)
        {
            return -1;
        }
        
        /* initialize threshold-gui */
        if(thresh_gui_init() < 0)
        {
            return -1;
        }
        
        /* initalize settings-gui */
        if(prefs_gui_init() < 0)
        {
            return -1;
        }
        
        /* initialize gStreamer-gui stuff */
        if(gstr_gui_init() < 0)
        {
            return -1;
        }            
        

    
        g_signal_connect(G_OBJECT
                         (glade_xml_get_widget
                          (gui.glade_xml, "button_dialog")), "clicked",
                         G_CALLBACK(cb_dialog_close), NULL);
    
        
    
        /*
         * set GUI to current source 
         */
        src_set_updateSrcGui(TRUE);
    
        /*
         * set version strings 
         */
        snprintf((char *) &temp, 254, "<span size=\"large\">v%s-%s</span>", 
                                            VERSION, REVISION);
                 
        gtk_label_set_markup(GTK_LABEL(glade_xml_get_widget
                              (gui.glade_xml, "label_version")),
                             (gchar *) & temp);
                             
        snprintf((char *) &temp, 254, "%s", BUILDDATE);
                 
        gtk_label_set_markup(GTK_LABEL(glade_xml_get_widget
                              (gui.glade_xml, "label_builddate")),
                             (gchar *) & temp);
                             
                             
        snprintf((char *) &temp, 254, "%s v%s - D.Hiepler (c) 2007-2013", PACKAGE, VERSION);
        gtk_window_set_title(GTK_WINDOW(glade_xml_get_widget(gui.glade_xml, "mainWindow")),(gchar *) &temp);
        
        /*
         * display everything 
         */
        gtk_widget_show_all(glade_xml_get_widget
                            (gui.glade_xml, "mainWindow"));
    
            
        /*
         * draw preview once (black) 
         */
        src_get()->draw_source = TRUE;
        src_get()->draw_dst = TRUE;
    
        /*
         * hide unselected outputs 
         */
        output_set_type(gtk_combo_box_get_active(GTK_COMBO_BOX
                                             (glade_xml_get_widget
                                              (gui.glade_xml,
                                               "combobox_out_type"))));
               
        /* hide yes-image */
        gtk_widget_hide(glade_xml_get_widget(gui.glade_xml,
                            "image_yes"));
                            
        src_set_updateSrcGui(TRUE);
    
        /*
         * best error-handling ever (tm)
         */
        return 0;
    }
    
    return -1;
}


/**
 * display a warning dialog
 * @param printf-like formatted string
 * @result complete url
 */
void gui_dialog(const char *fmt, ...)
{
	va_list ap;
	int length = 0;
	char *r = NULL;
	char tmp[1024];
	const char *fmt_s = fmt;
	
    
    if(gui.glade_xml)
    {
        
        /* determine how much space we need */
        va_start(ap, fmt);
        
        /* walk all args */
        while(*fmt)
        {
            
            switch (*fmt++)
            {
                /* escape? */
                case '%':
                    switch (*fmt)
                    {
                        case 'd':
                            snprintf((char *) &tmp, 1024, "%d", va_arg(ap, int));
                            length += strlen((char *) &tmp);
                            break;
                        
                        case 'f':
                            snprintf((char *) &tmp, 1024, "%f", va_arg(ap, double));
                            length += strlen((char *) &tmp);
                            break;
                        
                        case 's':
                            length += strlen(va_arg(ap, char *));
                            break;
                        
                        case 'c':
                            snprintf((char *) &tmp, 1024, "%c", (char) va_arg(ap, int));
                            length += strlen((char *) &tmp);
                            break;
                        
                        case '*':
                            length *= 2;
                            break;
                        
                        case '%':
                            length++;
                            break;
                        
                        default:
                            printf("%s(): Unknown sequence in format-string: '%c'",
                                __func__, (char) *fmt);
                            break;
                    }
                    fmt += 1;
                    break;
                
                default:
                    length++;
                    break;
            }
            
        }
        va_end(ap);
        length++;
        
        /* allocate memory for result */
        if((r = malloc(length)))
        {
            fmt = fmt_s;
            va_start(ap, fmt);
            vsnprintf(r, length, fmt, ap);
            va_end(ap);
            
            /* set dialog */
            gtk_label_set_text(GTK_LABEL
                           (glade_xml_get_widget
                            (gui_get_xml(), "label_dialog")),
                           g_locale_to_utf8(r, -1, NULL, NULL, NULL));
            
            /* show dialog */
            gtk_widget_show(glade_xml_get_widget
                        (gui_get_xml(), "dialog_warning"));
            
            /* free memory */
            free(r);
        }
        else
        {
            _ERROR printf("%s(): %s", __func__, strerror(errno));
        }
    }            
}


/** 
 * @} 
 */
